/**
 * 
 */
package ac.svn.accesscontrol.controller;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;

import ac.notification.event.INotificationListener;
import ac.notification.event.NotificationEvent;
import ac.notification.manager.NotificationRegistrar;
import ac.svn.accesscontrol.store.IConstants;
import ac.svn.accesscontrol.store.ISVNIdentifier;
import ac.svn.accesscontrol.store.ui.StatusItem;
import ac.svn.accesscontrol.utils.Utility;

/**
 * @author Ankush Chaudhary
 *
 */
public class StatusLabelController implements INotificationListener,
ISVNIdentifier,IConstants {

	private JLabel statusLabel;
	private ConcurrentLinkedQueue<StatusItem> statusMessages;
	private Timer statusUpdater;
	private static int updateInterval;
	private Border defBorder;

	public StatusLabelController()
	{
		defBorder				= (new JLabel()).getBorder();
		updateInterval 		= 350;
		statusMessages 	= new ConcurrentLinkedQueue<StatusItem>();
		statusUpdater 		= new Timer(updateInterval,new TimerTask());
		NotificationRegistrar.registerListener(this);
	}



	/** (non-Javadoc)
	 * @see ac.notification.event.INotificationListener#declaredSubscriptionSet()
	 */
	@Override
	public Set<String> declaredSubscriptionSet() {
		Set<String> subscriptions = new HashSet<String>();
		subscriptions.add(CMD_SHOW_STATUS_MESSAGE);
		return subscriptions;
	}

	/** (non-Javadoc)
	 * @see ac.notification.event.INotificationListener#receiveEvent(ac.notification.event.NotificationEvent)
	 */
	@Override
	public void receiveEvent(NotificationEvent ne) 
	{
		if(ne.getPropertyIdentifier().contains(CMD_SHOW_STATUS_MESSAGE))
		{
			showStatusMessageHandler(ne);   
		}
	}


	private void showStatusMessageHandler(NotificationEvent ne) 
	{
		StatusItem statusItem = (StatusItem) ne.getPropertyValue();

		//Make it thread safe.
		synchronized (statusMessages) 
		{
			//Create a temporary list that can be sorted.
			List<StatusItem> sortedList = new ArrayList<StatusItem>(statusMessages);
			sortedList.add(statusItem);
			Collections.sort(sortedList);

			//ReForm displayable status queue.
			statusMessages.clear();
			for(StatusItem item : sortedList)
			{
				statusMessages.add(item);
			}	    
		}

		//Check if timer is not running.
		if(false == statusUpdater.isRunning())
		{
			//Start timer.
			statusUpdater.start();
		}
	}



	/**
	 * @return the statusLabel
	 */
	public JLabel getStatusLabel() {
		return statusLabel;
	}



	/**
	 * @param statusLabel the statusLabel to set
	 */
	public void setStatusLabel(JLabel statusLabel) {
		this.statusLabel = statusLabel;
	}

	public class TimerTask implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent ae) 
		{
			try
			{
				//Check target component to be present.
				if(null == statusLabel)
				{
					return;
				}
				synchronized (statusMessages) 
				{
					//Stop if no message are there to display
					if(true == statusMessages.isEmpty())
					{
						statusUpdater.stop();
						statusLabel.setBorder(defBorder);
						return;
					}

					statusLabel.setBorder(new MatteBorder(0,0,5,0,Color.ORANGE));

					StatusItem statusItem = statusMessages.remove();

					//Display Text.
					statusLabel.setText(statusItem.getMessage());

					//Set Icon if present.
					if((null != statusItem.getIconURL())&&(false == statusItem.getIconURL().isEmpty()))
					{
						ImageIcon imageIcon = Utility.getImageIcon(statusItem.getIconURL());
						statusLabel.setIcon(imageIcon);
					}

					//Set Font if present.
					if(null != statusItem.getStatusFont())
					{
						statusLabel.setFont(statusItem.getStatusFont());
					}

					//Set Color if present
					if(null != statusItem.getStatusColor())
					{
						statusLabel.setForeground(statusItem.getStatusColor());
					}
				}
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
	}

}
